#ifndef UnstructMG_MG_COARSEN_HPP
#define UnstructMG_MG_COARSEN_HPP

#include "MG_types.hpp"
#include "par_CSRMatrix.hpp"

template<typename idx_t, typename setup_t, int dof>
void Coarsen(const idx_t coarsen_type, const par_CSRMatrix<idx_t, setup_t, setup_t, dof> * par_fine_mat,
    par_CSRMatrix<idx_t, setup_t, setup_t, 1> * & R_mat, par_CSRMatrix<idx_t, setup_t, setup_t, dof> * & par_coar_mat,
    par_CSRMatrix<idx_t, setup_t, setup_t, 1> * & P_mat, const CoarseConfig & config);
                            // coarsen_type         par_vec                     par_fine_mat
extern template void Coarsen(const int, const par_CSRMatrix_I32F64F64_DOF1 *, par_CSRMatrix_I32F64F64_DOF1 * &, par_CSRMatrix_I32F64F64_DOF1 * &, par_CSRMatrix_I32F64F64_DOF1 * &, const CoarseConfig &);
extern template void Coarsen(const int, const par_CSRMatrix_I32F64F64_DOF2 *, par_CSRMatrix_I32F64F64_DOF1 * &, par_CSRMatrix_I32F64F64_DOF2 * &, par_CSRMatrix_I32F64F64_DOF1 * &, const CoarseConfig &);
extern template void Coarsen(const int, const par_CSRMatrix_I32F64F64_DOF3 *, par_CSRMatrix_I32F64F64_DOF1 * &, par_CSRMatrix_I32F64F64_DOF3 * &, par_CSRMatrix_I32F64F64_DOF1 * &, const CoarseConfig &);
extern template void Coarsen(const int, const par_CSRMatrix_I32F64F64_DOF4 *, par_CSRMatrix_I32F64F64_DOF1 * &, par_CSRMatrix_I32F64F64_DOF4 * &, par_CSRMatrix_I32F64F64_DOF1 * &, const CoarseConfig &);

extern template void Coarsen(const int, const par_CSRMatrix_I32F32F32_DOF1 *, par_CSRMatrix_I32F32F32_DOF1 * &, par_CSRMatrix_I32F32F32_DOF1 * &, par_CSRMatrix_I32F32F32_DOF1 * &, const CoarseConfig &);
extern template void Coarsen(const int, const par_CSRMatrix_I32F32F32_DOF2 *, par_CSRMatrix_I32F32F32_DOF1 * &, par_CSRMatrix_I32F32F32_DOF2 * &, par_CSRMatrix_I32F32F32_DOF1 * &, const CoarseConfig &);
extern template void Coarsen(const int, const par_CSRMatrix_I32F32F32_DOF3 *, par_CSRMatrix_I32F32F32_DOF1 * &, par_CSRMatrix_I32F32F32_DOF3 * &, par_CSRMatrix_I32F32F32_DOF1 * &, const CoarseConfig &);
extern template void Coarsen(const int, const par_CSRMatrix_I32F32F32_DOF4 *, par_CSRMatrix_I32F32F32_DOF1 * &, par_CSRMatrix_I32F32F32_DOF4 * &, par_CSRMatrix_I32F32F32_DOF1 * &, const CoarseConfig &);



#endif